<?php
declare(strict_types=1);

namespace app\platform\business;

use app\common\model\Website as WebsiteModel;
use think\facade\Cache;

class Website extends PlatformBase
{
    private $_websiteObj = null;

    private const _DB_CONFIG_ERROR_MSG      = '数据库配置信息错误';
    private const _DB_NAME_EXISTS_ERROR_MSG = '数据库已存在';

    private const _WEBSITE_DATABASE_CONFIG_CACHE_KEY = 'website_database_config';

    public function __construct()
    {
        $this->_websiteObj = new WebsiteModel();
    }

    public function getAllWebsite(array $where = []): array
    {
        $rows = [];
        try {
            $rows = $this->_websiteObj->getAllWebsite($where);
        } catch (\Exception $e) {
            logErr('读取所有站点失败', sprintf('method:%s,err:%s', __METHOD__, $e->getMessage()));
        }

        return $rows;
    }

    public function getWebsiteList(int $page = 1, int $limit = 10, array $where = []): array
    {
        $rows  = [];
        $count = 0;
        try {
            $rows  = $this->_websiteObj->getWebsiteList($page, $limit, $where);
            $count = $this->_websiteObj->getWebsiteCount($where);
        } catch (\Exception $e) {
            logErr('读取站点列表失败', sprintf('method:%s,err:%s', __METHOD__, $e->getMessage()));
        }

        return ['rows' => $rows ? $rows->toArray() : [], 'count' => $count];
    }

    public function addWebsite(array $data): array
    {
        $data['db_password'] = encryptPwd($data['db_password']);
        try {
            return [self::_RESULT => $this->_websiteObj->addWebsite($data) && $this->_buildDatabaseConfigFile($data), self::_MESSAGE => self::_ADD_SUCCESS_MESSAGE];
        } catch (\Exception $e) {
            logErr('添加站点失败', sprintf('method:%s,err:%s', __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }

    public function findWebsiteById(int $id): array
    {
        $website = null;
        try {
            $website = $this->_websiteObj->findWebsiteById($id);
        } catch (\Exception $e) {
            logErr('通过主键读取站点详细信息失败', sprintf('method:%s,err:%s', __METHOD__, $e->getMessage()));
        }

        if (empty($website)) {
            return [];
        }

        return $website->toArray();
    }

    public function updateWebsite(int $id, array $data): array
    {
        $old          = $this->findWebsiteById($id);
        $data['code'] = $old['code'];
        if (!empty($data['db_password'])) {
            $data['db_password'] = encryptPwd($data['db_password']);
        } else {
            $data['db_password'] = $old['db_password'];
        }

        try {
            return [self::_RESULT => $this->_websiteObj->updateWebsite($id, $data) && $this->_buildDatabaseConfigFile($data), self::_MESSAGE => self::_UPDATE_SUCCESS_MESSAGE];
        } catch (\Exception $e) {
            logErr('通过主键更新站点信息失败', sprintf('method:%s,err:%s', __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }

    public function deleteWebsite(int $id): array
    {
        try {
            $website = $this->_websiteObj->findWebsiteById($id);
            if (empty($website)) {
                return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
            }

            $dbInfo = Cache::get(self::_WEBSITE_DATABASE_CONFIG_CACHE_KEY);
            if (is_array($dbInfo) && isset($dbInfo[$website['code']])) {
                unset($dbInfo[$website['code']]);
                Cache::set(self::_WEBSITE_DATABASE_CONFIG_CACHE_KEY, $dbInfo);
            }

            return [self::_RESULT => $this->_websiteObj->deleteWebsite($id), self::_MESSAGE => self::_DELETE_SUCCESS_MESSAGE];
        } catch (\Exception $e) {
            logErr('通过主键删除站点失败', sprintf('method:%s,err:%s', __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }

    public function executeInitSql(int $id): array
    {
        $website = null;
        try {
            $website = $this->_websiteObj->findWebsiteById($id);
            if (empty($website)) {
                return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
            }

            $conn = @mysqli_connect($website['db_host'], $website['db_user'], decryptPwd($website['db_password']));
            if (!$conn) {
                return [self::_RESULT => false, self::_MESSAGE => self::_DB_CONFIG_ERROR_MSG];
            }

            mysqli_query($conn, "set names utf8");

            $sql    = 'SHOW DATABASES LIKE \'' . $website['db_name'] . '\'';
            $result = @mysqli_query($conn, $sql);
            if ($result->num_rows) {
                return [self::_RESULT => false, self::_MESSAGE => self::_DB_NAME_EXISTS_ERROR_MSG];
            }

            mysqli_query($conn, "CREATE DATABASE IF NOT EXISTS `" . $website['db_name'] . "` default charset utf8mb4;");
            mysqli_select_db($conn, $website['code']);

            $sql    = file_get_contents('../app/platform/sql/standard.sql');
            $sql    = str_replace('{prefix}', $website['db_prefix'], $sql);
            $sqlArr = explode(';', $sql);
            foreach ($sqlArr as $v) {
                $temp = [];
                $preg = "/(\/\*.*\*\/)/isU";
                preg_match_all($preg, trim($v), $temp);
                $v = str_replace($temp[1], '', $v);
                if (!$v) {
                    continue;
                }

                mysqli_query($conn, $v);
            }

            mysqli_close($conn);

            return [self::_RESULT => true, self::_MESSAGE => self::_EXECUTE_INIT_SQL_SUCCESS_MESSAGE];
        } catch (\Exception $e) {
            logErr('通过主键初始站点数据失败', sprintf('website_code:%s,method:%s,err:%s', $website['code'], __METHOD__, $e->getMessage()));
        }

        return [self::_RESULT => false, self::_MESSAGE => self::_SYSTEM_ERROR_MESSAGE];
    }

    private function _buildDatabaseConfigFile(array $data): bool
    {
        $password = decryptPwd($data['db_password']);
        $dbInfo   = Cache::get(self::_WEBSITE_DATABASE_CONFIG_CACHE_KEY);
        if (!is_array($dbInfo)) {
            $dbInfo = [];
        }

        $dbInfo[$data['code']] = [
            // 数据库类型
            'type'            => env('database.DB_TYPE', 'mysql'),
            // 服务器地址
            'hostname'        => $data['db_host'],
            // 数据库名
            'database'        => $data['db_name'],
            // 用户名
            'username'        => $data['db_user'],
            // 密码
            'password'        => $password,
            // 端口
            'hostport'        => $data['db_port'],
            // 数据库连接参数
            'params'          => [],
            // 数据库编码默认采用utf8
            'charset'         => env('database.DB_CHARSET', 'utf8'),
            // 数据库表前缀
            'prefix'          => $data['db_prefix'],

            // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
            'deploy'          => 0,
            // 数据库读写是否分离 主从式有效
            'rw_separate'     => false,
            // 读写分离后 主服务器数量
            'master_num'      => 1,
            // 指定从服务器序号
            'slave_no'        => '',
            // 是否严格检查字段是否存在
            'fields_strict'   => true,
            // 是否需要断线重连
            'break_reconnect' => false,
            // 监听SQL
            'trigger_sql'     => env('app_debug', true),
            // 开启字段缓存
            'fields_cache'    => false,
        ];

        Cache::set(self::_WEBSITE_DATABASE_CONFIG_CACHE_KEY, $dbInfo);
        return true;
    }
}
